home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Mac Power 1996 September
/
MACPOWER-1996-09.ISO.7z
/
MACPOWER-1996-09.ISO
/
第2特集:プラグイン大集合
/
PIC2 Save
/
p2save.c
< prev
next >
Wrap
Text File
|
1995-01-16
|
18KB
|
862 lines
/*
* PIC2 高圧縮/ベタフォーマットの展開 by やなぎさわ
*
*/
#include "pic2.h"
/* 現在のP2の中の変数のコピー (^^; */
static ushort aa;
static ushort cc;
static char cache_hit_c;
static ushort bit_buf;
static long n_bit;
static short n_bit_buf;
static long xw;
static long ymax;
static uchar *fbufp;
static long n_fbuf;
static P2 *p2;
static pix *vram_prev;
static pix *vram_now;
static pix *vram_next;
static schar *flag_now;
static schar *flag_next;
static schar *flag2_now;
static schar *flag2_next;
static schar *flag2_next2;
static pix (_HUGE_ * cache)[N_COLOR_CACHE+1];
static ushort *cache_pos;
static ushort *mulu_tab;
static long *c_sum,*c_0_sum;
static char press_pass;
static short ynow;
static pix (*write_color)( pix x);
/* エラー時の脱出用 */
static jmp_buf jmp_env;
/*
* 1バイトファイルに書き出し
*/
static void
write_byte( uchar a)
{
*fbufp++ = a;
if ( --n_fbuf <= 0) {
fbufp = p2->fbuf;
n_fbuf = N_FBUF;
if ( write_file( p2, fbufp, N_FBUF) != N_FBUF) {
p2errno = p2->errno = dskFulErr; //ENOSPC;
longjmp( jmp_env, 1);
}
}
}
/*
* 1ビットファイルに出力 (繰り上げ対策付き)
*
* 繰り上げ対策のためにすぐには書き出さない
* そのために'0'の次に'1'が n_bitつづいている事を覚えていて
* そこに'0'が来ると、前の'0'を出してn_bitだけ'1'を出す
* '1'が来ると、n_bitを増やす
* ただし、'0'が有無を'have_zero'にとっておく
*/
static char have_zero;
#define bit_nz_write() (n_bit++)
static void
bit_z_write( void)
{
long i;
if ( have_zero) {
bit_buf = bit_buf + bit_buf; /* bitバッファに'0'を入れる */
if ( ++n_bit_buf == 8) { /* bitバッファがフルなら書き出す */
write_byte( bit_buf);
n_bit_buf = 0;
}
}
for ( i = 0; i < n_bit; i++) { /* n_bitだけ'1'があるので、それを書きだす */
bit_buf = bit_buf + bit_buf + 1;
if ( ++n_bit_buf == 8) {
write_byte( bit_buf);
n_bit_buf = 0;
}
}
have_zero = 1;
n_bit = 0;
}
/* 繰り上げ */
static void
bit_up( void)
{
bit_buf = bit_buf + bit_buf + 1; /* 今までとっておいた'0'が繰り上がり'1'になる */
if ( ++n_bit_buf == 8) {
write_byte( bit_buf);
n_bit_buf = 0;
}
if ( n_bit == 0) {
have_zero = 0;
} else {
long i;
for ( i = 0; i < n_bit - 1; i++) { /* n_bitだけあった'1'は繰り上げで'0'になってしまう */
bit_buf = bit_buf + bit_buf;
if ( ++n_bit_buf == 8) {
write_byte( bit_buf);
n_bit_buf = 0;
}
}
have_zero = 1;
}
n_bit = 0;
}
/*
* ビットのバッファのフラッシュ
*/
static void
bit_buf_flush( void)
{
long i;
for ( i = 0; i < 16; i++) {
if ( cc & 0x8000) bit_nz_write();
else bit_z_write();
cc = cc + cc;
}
bit_z_write();
bit_buf <<= 8 - n_bit_buf;
write_byte(bit_buf);
}
/*
* ファイルバッファのフラッシュ
*/
static void
fbuf_flush( void)
{
long n;
bit_buf_flush();
n = N_FBUF - n_fbuf;
if ( write_file( p2, p2->fbuf, n) != n) {
longjmp( jmp_env, 1);
}
}
/*
* 算術圧縮 確率空間 'c'で 'n'(0 or 1)を符号化
*/
static void
bit_encode( long n, long c)
{
ushort pp;
if ( press_pass == 0) {
c_sum[c]++;
if ( n == 0) c_0_sum[c]++;
return;
}
pp = mulu_tab[(aa & 0x7f00) / 2 + c];
if ( n != 0) {
ulong lcc = (ulong)cc + pp;
if ( lcc >= 0x10000) {
bit_up();
}
cc = lcc;
aa = aa - pp;
while ( aa < 0x8000u) {
if ( cc & 0x8000) bit_nz_write();
else bit_z_write();
cc *= 2;
aa *= 2;
}
} else {
aa = pp;
while ( aa < 0x8000u) {
if ( cc & 0x8000) bit_nz_write();
else bit_z_write();
cc *= 2;
aa *= 2;
}
}
}
/*
* 1バイト(多値)データの符号化 上限付き
*/
static void
nbyte_encode( long n, long c, long max)
{
short i;
for ( i = 0; i < n; i++) {
bit_encode( 0, c + i);
}
if ( n < max) bit_encode( 1, c + n);
}
/*
* nを空間cで記録
*/
static void
nn_encode( long n, long c)
{
if ( n < 1) {
bit_encode( 1, c);
} else if ( n < 1 + 2) {
bit_encode( 0, c);
bit_encode( 1, c + 1);
n -= 1;
bit_encode( n & 1, c + 8);
} else if ( n < 1 + 2 + 4) {
bit_encode( 0, c);
bit_encode( 0, c + 1);
bit_encode( 1, c + 2);
n -= 1 + 2;
bit_encode( n & 1, c + 8);
bit_encode( n & 2, c + 9);
} else if ( n < 1 + 2 + 4 + 8) {
bit_encode( 0, c);
bit_encode( 0, c + 1);
bit_encode( 0, c + 2);
bit_encode( 1, c + 3);
n -= 1 + 2 + 4;
bit_encode( n & 1, c + 8);
bit_encode( n & 2, c + 9);
bit_encode( n & 4, c + 10);
} else if ( n < 1 + 2 + 4 + 8 + 16) {
bit_encode( 0, c);
bit_encode( 0, c + 1);
bit_encode( 0, c + 2);
bit_encode( 0, c + 3);
bit_encode( 1, c + 4);
n -= 1 + 2 + 4 + 8;
bit_encode( n & 1, c + 8);
bit_encode( n & 2, c + 9);
bit_encode( n & 4, c + 10);
bit_encode( n & 8, c + 11);
} else if ( n < 1 + 2 + 4 + 8 + 16 + 32) {
bit_encode( 0, c);
bit_encode( 0, c + 1);
bit_encode( 0, c + 2);
bit_encode( 0, c + 3);
bit_encode( 0, c + 4);
bit_encode( 1, c + 5);
n -= 1 + 2 + 4 + 8 + 16;
bit_encode( n & 1, c + 8);
bit_encode( n & 2, c + 9);
bit_encode( n & 4, c + 10);
bit_encode( n & 8, c + 11);
bit_encode( n & 16, c + 12);
} else if ( n < 1 + 2 + 4 + 8 + 16 + 32 + 64) {
bit_encode( 0, c);
bit_encode( 0, c + 1);
bit_encode( 0, c + 2);
bit_encode( 0, c + 3);
bit_encode( 0, c + 4);
bit_encode( 0, c + 5);
bit_encode( 1, c + 6);
n -= 1 + 2 + 4 + 8 + 16 + 32;
bit_encode( n & 1, c + 8);
bit_encode( n & 2, c + 9);
bit_encode( n & 4, c + 10);
bit_encode( n & 8, c + 11);
bit_encode( n & 16, c + 12);
bit_encode( n & 32, c + 13);
} else if ( n < 1 + 2 + 4 + 8 + 16 + 32 + 64 + 128) {
bit_encode( 0, c);
bit_encode( 0, c + 1);
bit_encode( 0, c + 2);
bit_encode( 0, c + 3);
bit_encode( 0, c + 4);
bit_encode( 0, c + 5);
bit_encode( 0, c + 6);
bit_encode( 1, c + 7);
n -= 1 + 2 + 4 + 8 + 16 + 32 + 64;
bit_encode( n & 1, c + 8);
bit_encode( n & 2, c + 9);
bit_encode( n & 4, c + 10);
bit_encode( n & 8, c + 11);
bit_encode( n & 16, c + 12);
bit_encode( n & 32, c + 13);
bit_encode( n & 64, c + 14);
} else {
bit_encode( 0, c);
bit_encode( 0, c + 1);
bit_encode( 0, c + 2);
bit_encode( 0, c + 3);
bit_encode( 0, c + 4);
bit_encode( 0, c + 5);
bit_encode( 0, c + 6);
bit_encode( 0, c + 7);
}
}
/*
* 連鎖の符号化
*/
static void
press_chain( long x)
{
long d = 0;
long b = -flag_now[ x]; /* 現在の点の確率空間は、この点がどこの連鎖だったかによる */
pix c = vram_now[x];
if ( b < 0) b = 0;
/* 左右の境界チェックが無いけど、flagの配列を左右余分にとってあり、それが0なので
* 特別に (x - 1 < 0)などのチェックはしていない
*/
if ( flag_next[ x] == 1 && vram_next[ x] == c) {
d = 1;
flag_next[ x] = -1;
} else if ( flag_next[ x - 1] == 1 && vram_next[ x - 1] == c) {
d = 2;
flag_next[ x - 1] = -2;
} else if ( flag_next[ x + 1] == 1 && vram_next[ x + 1] == c) {
d = 3;
flag_next[ x + 1] = -3;
} else if ( flag_next[ x - 2] == 1 && vram_next[ x - 2] == c) {
d = 4;
flag_next[ x - 2] = -4;
} else if ( flag_next[ x + 2] == 1 && vram_next[ x + 2] == c) {
/* 右2つは出来るだけ作らないようにする。下の条件にマッチすれば
* 今連鎖を取らなくても数画素後に連鎖となる。
*/
if ( (flag_now[ x + 2] != 0 && vram_now[ x + 2] == c)
|| (flag_now[ x + 1] != 0 && vram_now[ x + 1] == c)
|| (flag_now[ x + 3] != 0 && vram_now[ x + 3] == c)
) { /* なしね */
nbyte_encode( 0, 80 + 6 * b, 5);
return;
}
d = 5;
flag_next[ x + 2] = -5;
}
nbyte_encode( d, 80 + 6 * b, 5);
}
/*
* 16bit色の書き出し
*/
static void
write_color8( uchar cc)
{
short i,j;
uchar *cache8 = (uchar *)cache_pos;
for ( i = 0; i < 256; i++) {
if ( cache8[i] == cc) break;
}
nn_encode( i, 32);
for ( j = i; j > 0; j--) {
cache8[ j] = cache8[ j - 1];
}
cache8[ 0] = cc;
}
#define N_CACHE8_S 5
#define N_CACHE8 ((1<<N_CACHE8_S)-1)
static void
write_color16( pix x)
{
pix cc,*p,*pp;
short i,j,k;
k = vram_now[ x - 1] & 255;
cc = vram_now[ x];
p = cache[k];
for ( i = 0; i < N_CACHE8; i++) {
if ( cc == *p++) break;
}
if ( i == N_CACHE8) {
pp = p - 1;
for ( j = N_CACHE8; j > 0; j--) {
*--p = *--pp;
}
cache[ k][0] = cc;
bit_encode( 1, cache_hit_c);
cache_hit_c = 16;
write_color8( cc >> 8);
write_color8( cc & 255);
} else {
/* *--p = cache[k][i/2]; */
cache[k][i] = cache[k][i/2];
cache[k][i/2] = cache[k][0];
cache[k][0] = cc;
bit_encode( 0, cache_hit_c);
cache_hit_c = 15;
nn_encode( i, 17);
}
/* printf("%d/%d:%ld,%d,%d¥n", ynow - 1, x, cc, k, i); */
}
/*
* 色の符号化
*/
#define putnum15( xn, xa, xb) { ¥
short n; ¥
if ( xa >= 16) { ¥
if ( xb > xa) n = ( xb - xa) * 2 - 1; ¥
else if ( xa - (31 - xa) > xb) n = 31 - xb; ¥
else n = ( xa - xb) * 2; ¥
} else { ¥
if ( xb <= xa) n = ( xa - xb) * 2; ¥
else if ( 2 * xa < xb) n = xb; ¥
else n = ( xb - xa) * 2 - 1; ¥
} ¥
nn_encode( n, xn); ¥
}
static void
write_color15( pix x)
{
pix c1,c2,cc;
short g0,r0,b0,r,g,b;
short i,j;
ushort k;
pix *p,*pp;
cc = vram_now[ x];
c1 = vram_prev[ x];
k = ((c1 >> 7) & 0x1c0) + ((c1 >> 5) & 0x38) + ((c1 >> 3) & 7);
p = cache[k];
for ( i = 0; i < N_COLOR_CACHE; i++) {
if ( cc == *p++) break;
}
if ( i == N_COLOR_CACHE) {
pp = p - 1;
for ( j = i; j > 0; j--) {
*--p = *--pp;
}
cache[ k][ 0] = cc;
bit_encode( 1, cache_hit_c);
cache_hit_c = 16;
c2 = vram_now[ x - 1];
g = ((c1 & 0xf800u) + (c2 & 0xf800u)) >> 12;
r = ((c1 & 0x07c0u) + (c2 & 0x07c0u)) >> 7;
b = ((c1 & 0x003eu) + (c2 & 0x003eu)) >> 2;
g0 = (cc >> 11) & 31;
r0 = (cc >> 6) & 31;
b0 = (cc >> 1) & 31;
r = r + g0 - g;
if ( r < 0) r = 0;
else if ( r > 31) r = 31;
b = b + g0 - g;
if ( b < 0) b = 0;
else if ( b > 31) b = 31;
putnum15( 32, g, g0);
putnum15( 48, r, r0);
putnum15( 64, b, b0);
} else {
*--p = cache[k][i/2];
cache[k][i/2] = cache[k][0];
cache[ k][ 0] = cc;
bit_encode( 0, cache_hit_c);
cache_hit_c = 15;
nn_encode( i, 17);
}
}
#define putnum24( xn, xa, xb) { ¥
short n; ¥
if ( xa >= 128) { ¥
if ( xb > xa) n = ( xb - xa) * 2 - 1; ¥
else if ( xa - (255 - xa) > xb) n = 255 - xb; ¥
else n = ( xa - xb) * 2; ¥
} else { ¥
if ( xb <= xa) n = ( xa - xb) * 2; ¥
else if ( 2 * xa < xb) n = xb; ¥
else n = ( xb - xa) * 2 - 1; ¥
} ¥
nn_encode( n, xn); ¥
}
static void
write_color24( pix x)
{
pix c1,c2,cc;
long g0,r0,b0,r,g,b;
long i,j,k;
pix *p,*pp;
cc = vram_now[ x];
c1 = vram_prev[ x];
/* RRRrrrrrGGGgggggBBBbbbbb -> RRRGGGBBB */
k = (c1 >> (16 + 5 - 6) & 0x1c0) /* red */
+ (c1 >> ( 8 + 5 - 3) & 0x038) /* green */
+ (c1 >> ( 0 + 5 - 0) & 0x007); /* blue */
p = cache[k];
for ( i = 0; i < N_COLOR_CACHE; i++) {
if ( cc == *p++) break;
}
if ( i == N_COLOR_CACHE) {
pp = p - 1;
for ( j = i; j > 0; j--) {
*--p = *--pp;
}
cache[ k][ 0] = cc;
bit_encode( 1, cache_hit_c);
cache_hit_c = 16;
c2 = vram_now[ x - 1];
g = ((c1 & 0x00ff00u) + (c2 & 0x00ff00u)) >> (8 + 1);
r = ((c1 & 0xff0000u) + (c2 & 0xff0000u)) >> (16 + 1);
b = ((c1 & 0x0000ffu) + (c2 & 0x0000ffu)) >> (0 + 1);
g0 = (cc >> 8) & 255;
r0 = (cc >> 16) & 255;
b0 = cc & 255;
r = r + g0 - g;
if ( r < 0) r = 0;
else if ( r > 255) r = 255;
b = b + g0 - g;
if ( b < 0) b = 0;
else if ( b > 255) b = 255;
putnum24( 32, g, g0);
putnum24( 48, r, r0);
putnum24( 64, b, b0);
} else {
*--p = cache[k][i/2];
cache[k][i/2] = cache[k][0];
cache[ k][ 0] = cc;
bit_encode( 0, cache_hit_c);
cache_hit_c = 15;
nn_encode( i, 17);
}
}
/* 構造体アクセスをケチするため */
static void
para_out( void)
{
fbufp = p2->fbufp;
n_fbuf = p2->n_fbuf;
bit_buf = p2->bit_buf;
n_bit_buf = p2->n_bit_buf;
n_bit = p2->data;
ymax = SHORT2short( p2->blk.y_wid) - 1;
xw = SHORT2short( p2->blk.x_wid);
aa = p2->aa;
cc = p2->cc;
press_pass = p2->dd;
cache_hit_c = p2->cache_hit_c;
write_color = (pix (*)(pix))p2->func;
ynow = p2->ynow;
vram_prev = p2->vram_prev + 4;
vram_now = p2->vram_now + 4;
vram_next = p2->vram_next + 4;
flag_now = p2->flag_now + 4;
flag_next = p2->flag_next + 4;
flag2_now = p2->flag2_now + 4;
flag2_next = p2->flag2_next + 4;
flag2_next2 = p2->flag2_next2 + 4;
cache = p2->cache;
mulu_tab = p2->mulu_tab;
c_sum = (long *)mulu_tab;
c_0_sum = c_sum + N_CONTEXT + 1;
cache_pos = p2->cache_pos;
}
static void
para_in( void)
{
void *p;
p2->fbufp = fbufp;
p2->n_fbuf = n_fbuf;
p2->bit_buf = bit_buf;
p2->n_bit_buf = n_bit_buf;
p2->data = n_bit;
p2->aa = aa;
p2->cc = cc;
p2->dd = press_pass;
p2->cache_hit_c = cache_hit_c;
p2->func = (pix (*)(pix))write_color;
p = p2->vram_prev;
p2->vram_prev = p2->vram_now;
p2->vram_now = p2->vram_next;
p2->vram_next = p;
p = p2->flag_now;
p2->flag_now = p2->flag_next;
p2->flag_next = p;
p = p2->flag2_now;
p2->flag2_now = p2->flag2_next;
p2->flag2_next = p2->flag2_next2;
p2->flag2_next2 = p;
p2->ynow = ynow;
}
/*
* 1行 圧縮
*/
static void
line_press2( void)
{
short x;
long a;
pix cc;
if ( SHORT2short( p2->header.depth) == 8) {
cc = vram_now[ xw * 2 - 2];
cc = cc * 256 + vram_now[ xw * 2 - 1];
} else {
cc = vram_now[ xw - 1]; /* ひとつ前の色 */
}
vram_next[ -1] = cc;
/* 変化点をマーク */
for ( x = 0; x < xw; x++) {
pix c = vram_next[ x];
if ( cc != c) {
flag_next[ x] = 1;
cc = c;
} else flag_next[ x] = 0;
}
for ( x = 0; x < xw; x++) {
a = flag_now[ x];
if ( a == 1) { /* 変化点 */
/* 変化点の回りに変化点は多くなるので */
flag2_now[ x + 1]++; flag2_now[ x + 2]++;
flag2_next[ x - 1]++; flag2_next[ x ]++; flag2_next[ x + 1]++;
flag2_next2[ x - 1]++; flag2_next2[ x ]++; flag2_next2[ x + 1]++;
/* 回りの変化点の多さで確率空間を切替えて、変化点の位置を記録 */
bit_encode( 1, flag2_now[ x]);
/* 色を記録 */
write_color( x);
/* 一番下でなければ連鎖を記録
* (ynow は実際にセーブしているライン+1が入っている)
*/
if ( ynow - 1 < ymax) press_chain( x);
} else if ( a == 0) { /* 連鎖上でない */
/* 回りの変化点の多さで確率空間を切替えて記録 */
bit_encode( 0, flag2_now[ x]);
} else { /* 連鎖上 */
/* 一番下でなければ次の連鎖を記録 */
if ( ynow - 1 < ymax) press_chain( x);
}
}
}
/*
* 行単位の圧縮で最初/最終ラインの処理をする
*/
long
line_press( P2 *pp2, pix **line)
{
if ( setjmp( jmp_env) != 0) return ( -1);
p2 = pp2;
para_out();
if ( SHORT2short( pp2->header.depth) == 8) {
short i,j;
xw = (xw + 1) / 2;
for ( i = j = 0; i < xw; i++) {
ushort hi = vram_next[ j++];
ushort low = vram_next[ j++];
vram_next[ i] = hi * 256 + low;
}
}
memset( flag2_next2 - 4, 0, (8 + xw) * sizeof( flag2_next2[0]));
if ( ynow == 0) { /* 先頭ラインの時 */
short x,i;
pix ccc;
if ( press_pass != 0) { /* 圧縮 pass */
unsigned short c_tab[N_CONTEXT];
/* fprintf( stderr, "press pass¥n");*/
for ( i = 0; i < N_CONTEXT; i++) {
ulong a, b;
a = c_0_sum[i];
b = c_sum[i];
while ( a > 32767) { /* 下で65536掛けた時に溢れないように */
a >>= 1;
b >>= 1;
}
if ( a == b) c_tab[i] = 0xffffu; /* b==0 もここになる */
else c_tab[i] = (65536uL * a) / b; /* a < b なので 65536以下 */
}
for ( i = 0; i < 16384; i++) {
mulu_tab[i] = (ulong)((i >> 7) + 128) * c_tab[i & 127] / 256;
if ( mulu_tab[i] == 0) mulu_tab[i] = 1; /* 0があるとだめだから */
}
p2errno = 0;
for ( i = 0; i < N_CONTEXT; i++) {
write_short( p2, c_tab[i]);
}
if ( p2errno != 0) return ( -1);
memset( vram_now, 0, xw * sizeof( vram_now[0]));
} else { /* 統計 pass */
memset( c_0_sum, 0, N_CONTEXT * sizeof( c_0_sum[0]));
memset( c_sum, 0, N_CONTEXT * sizeof( c_sum[0]));
}
/* フラグなどの初期化 */
l_memset( cache, 0, 8 * 8 * 8 * (long)sizeof( cache[0]));
memset( flag2_next - 4, 0, (8 + xw) * sizeof( flag2_next[0]));
memset( flag2_next2 - 4, 0, (8 + xw) * sizeof( flag2_next2[0]));
for ( i = 0; i < 256; i++) {
uchar *p = (uchar *)cache_pos;
p[i] = i;
}
vram_next[ -1] = ccc = 0;
for ( x = 0; x < xw; x++) {
pix c = vram_next[ x];
if ( ccc != c) {
flag_next[ x] = 1;
ccc = c;
} else flag_next[ x] = 0;
}
aa = 0xffff;
cc = 0;
n_bit = 0;
fbufp = p2->fbuf;
n_fbuf = N_FBUF;
n_bit_buf = 0;
bit_buf = 0;
have_zero = 0;
cache_hit_c = 16;
} else { /* 2ライン目から実際にセーブをする。これは1ライン先のデータが必要だから */
line_press2();
}
if ( ynow == ymax) {
/* 最後のラインの時は次のラインはもう無いので、これをセーブ */
ynow++;
para_in();
para_out();
if ( SHORT2short( pp2->header.depth) == 8) xw = (xw + 1) / 2;
line_press2();
}
/* 次のデータを入れて欲しいライン (vram_prevは次回 vram_nextになる)*/
if ( line != NULL) *line = vram_prev;
ynow++;
if ( ynow - 1 < ymax) { /* 最終ライン(終り)でなければ */
para_in(); /* P2にパラメータ入れる(戻す) */
return ( ynow);
} else { /* おわり */
if ( press_pass == 0) { /* 統計パス */
press_pass = 1; /* 次回から圧縮パス */
ynow = 0;
para_in(); /* P2にパラメータ入れる(戻す) */
return ( 0); /* 次回は圧縮パスだよん */
} else {
para_in(); /* P2にパラメータ入れる(戻す) */
p2errno = 0;
fbuf_flush(); /* bitバッファを書き出して */
return ( -2); /* おわり */
}
}
}
/*
* 算術圧縮部の初期化
*/
long
p2ss_sv_init( P2 *p2, pix **line)
{
p2->ynow = 0;
/* 色の記録関数のセット */
switch ( SHORT2short( p2->header.depth)) {
case 24:
p2->func = (pix (*)())write_color24;
break;
case 15:
p2->func = (pix (*)())write_color15;
break;
case 8:
p2->func = (pix (*)())write_color16;
break;
default:
p2errno= p2->errno = P2E_BADFORM;
return ( -1);
}
/* 次ライン関数をセット */
p2->nextline = line_press;
if ( line != NULL) *line = p2->vram_next + 4;
p2errno = 0;
seek_file( p2, p2->next_pos + SIZE_OF_BLK);
if ( p2errno == 0) return ( 0);
return ( -1);
}
/* eof */